package dev.ece.suit.hexmap.terrain;

import java.util.List;

import dev.ece.suit.hexmap.MapCell;
import dev.ece.suit.hexmap.MapCrevice;
import dev.ece.suit.hexmap.MapTriangle;
import dev.ece.suit.hexmap.MapTriangleCreator;
import dev.ece.suit.hexmap.TerrainModelCreator;
import dev.ece.util.lib.Vector2f;
import dev.ece.util.lib.Vector3f;
import dev.ece.util.tools.Direction;

public class SimpleMapTriangleCreator implements MapTriangleCreator {

	private TerrainModelCreator terrainModelCreator;
	
	private int count;
	
	
	public SimpleMapTriangleCreator(TerrainModelCreator terrainModelCreator) {
		this.terrainModelCreator = terrainModelCreator;	
		this.count = createCount();
	}
	
	protected int createCount() {
		if((getTerrainModelCreator().getMapCreviceCreator().rows() & 0) > 0) {
			throw new IllegalArgumentException("MapCreviceCreator.rows()必须返回偶数");
		}
		int vrow = getTerrainModelCreator().getMapCreviceCreator().rows() + 1;
		return 3 * 4 + (vrow / 2 - 1) * 6; 
	}
	
	@Override
	public MapTriangle create(int index, MapCell left, MapCell center, MapCell right, int direction) {
		int first = index * count();
		int cols = getTerrainModelCreator().getMapCreviceCreator().rows();
		int creviceLastCol = getTerrainModelCreator().getMapCreviceCreator().size() - 1;
		MapCell[] cells = createMapCells(direction, left, center, right);
		MapCrevice[] crevices = createMapCrevices(direction, cells);
		int rows = crevices.length;
		Vector3f[][] vertice = new Vector3f[rows][];
		Vector3f[][] normals = new Vector3f[rows][];
		Vector2f[][] uv = new Vector2f[rows][];
		Vector2f[][] alpha = new Vector2f[rows][];
		if(Direction.DIRECTION_0 == direction) {
			MapCrevice crevice = crevices[0];
			vertice[0] = new Vector3f[cols];
			normals[0] = new Vector3f[cols];
			uv[0] = new Vector2f[cols];
			alpha[0] = new Vector2f[cols];
			int col = 0;
			float rate = 1.0f / (cols + 1);
			float value = 0;
			for(int i=cols; i>0; i--) {
				vertice[0][col] = crevice.getVertice()[i][0];
				normals[0][col] = crevice.getNormals()[i][0];
				uv[0][col] = crevice.getUv()[i][0];
				alpha[0][col] = new Vector2f(1f - value, value);
				value += rate;
				col ++;
			}
			
			crevice = crevices[1];
			vertice[1] = new Vector3f[cols];
			normals[1] = new Vector3f[cols];
			uv[1] = new Vector2f[cols];
			alpha[1] = new Vector2f[cols];
			col = 0;
			value = 1;
			for(int i=0; i<cols; i++) {
				vertice[1][col] = crevice.getVertice()[i][creviceLastCol];
				normals[1][col] = crevice.getNormals()[i][creviceLastCol];
				uv[1][col] = crevice.getUv()[i][creviceLastCol];
				alpha[1][col] = new Vector2f(0, value);
				value -= rate;
				col ++;
			}
			
			crevice = crevices[2];
			vertice[2] = new Vector3f[cols];
			normals[2] = new Vector3f[cols];
			uv[2] = new Vector2f[cols];
			alpha[2] = new Vector2f[cols];
			col = 0;
			value = 0;
			for(int i=0; i<cols; i++) {
				vertice[2][col] = crevice.getVertice()[i][creviceLastCol];
				normals[2][col] = crevice.getNormals()[i][creviceLastCol];
				uv[2][col] = crevice.getUv()[i][creviceLastCol];
				alpha[2][col] = new Vector2f(value, 0);
				value += rate;
				col ++;
			}
		} else {
			MapCrevice crevice = crevices[0];
			vertice[0] = new Vector3f[cols];
			normals[0] = new Vector3f[cols];
			uv[0] = new Vector2f[cols];
			alpha[0] = new Vector2f[cols];
			int col = 0;
			float rate = 1.0f / (cols + 1);
			float value = 0;
			for(int i=0; i<cols; i++) {
				vertice[0][col] = crevice.getVertice()[i][creviceLastCol];
				normals[0][col] = crevice.getNormals()[i][creviceLastCol];
				uv[0][col] = crevice.getUv()[i][creviceLastCol];
				alpha[0][col] = new Vector2f(value, 0);
				value += rate;
				col ++;
			}
			
			crevice = crevices[1];
			vertice[1] = new Vector3f[cols];
			normals[1] = new Vector3f[cols];
			uv[1] = new Vector2f[cols];
			alpha[1] = new Vector2f[cols];
			col = 0;
			value = 0;
			for(int i=cols; i>0; i--) {
				vertice[1][col] = crevice.getVertice()[i][0];
				normals[1][col] = crevice.getNormals()[i][0];
				uv[1][col] = crevice.getUv()[i][0];
				alpha[1][col] = new Vector2f(1.0f - value, value);
				value += rate;
				col ++;
			}
			
			crevice = crevices[2];
			vertice[2] = new Vector3f[cols];
			normals[2] = new Vector3f[cols];
			uv[2] = new Vector2f[cols];
			alpha[2] = new Vector2f[cols];
			col = 0;
			value = 1;
			for(int i=cols; i>0; i--) {
				vertice[2][col] = crevice.getVertice()[i][0];
				normals[2][col] = crevice.getNormals()[i][0];
				uv[2][col] = crevice.getUv()[i][0];
				alpha[2][col] = new Vector2f(0, value);
				value -= rate;
				col ++;
			}
		}
		return new MapTriangle(cells, crevices, direction, vertice, normals, uv, alpha, first);
	}
	
	protected MapCell[] createMapCells(int direction, MapCell left, MapCell center, MapCell right) {
		if(Direction.DIRECTION_0 == direction) {
			return new MapCell[] {left, right, center};
		} else if(Direction.DIRECTION_1 == direction) {
			return new MapCell[] {left, center, right};
		} else {
			throw new IllegalArgumentException("direction参数错误");
		}
	}
	
	protected MapCrevice[] createMapCrevices(int direction, MapCell[] cells) {
		return new MapCrevice[] {
			cells[0].getNeighbors()[4],
			cells[1].getNeighbors()[0],
			cells[2].getNeighbors()[2]
		};
	}
	
	@Override
	public int count() {
		return count;
	}

	@Override
	public void fillData(MapTriangle triangle, List<Vector3f> vertice, List<Vector2f> uv, List<Vector3f> normals,
			List<Vector2f> alpha) {
		int centerIndex = getTerrainModelCreator().getMapCreviceCreator().rows() / 2;
		

	}

	public TerrainModelCreator getTerrainModelCreator() {
		return terrainModelCreator;
	}

}
